package br.com.felix.easyclearcase.tasks;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * This class is nothing more than a Thread with a few more functionalities, like
 * a status, and the hability to be cancelled.
 * */
public abstract class Task extends Thread implements Comparable<Task>{
	
	/**
	 * Possible states a task may be.
	 * */
	public enum TaskStatus {NOT_STARTED, IN_PROGRESS, COMPLETE_SUCCESS, COMPLETE_FAIL, STOPPING, CANCELLED};
	
	/**
	 * Possible task priorities.
	 * */
	public enum TaskPriority {LOW, NORMAL, HIGH};
	
	/**
	 * Current task status.
	 * */
	private TaskStatus status = TaskStatus.NOT_STARTED;
	
	/**
	 * Which time the task has started running.
	 * */
	private Date taskStartTime = null;
	
	/**
	 * flag to cancel task.
	 * */
	protected boolean cancelled = false;
	
	public Task(){
		addTaskStatusListener(new TaskStatusListener(){
			@Override
			public void statusChanged(TaskStatus oldValue, TaskStatus newValue) {
				if(newValue == TaskStatus.IN_PROGRESS){
					taskStartTime = new Date();
				}
			}
		});
	}
	
	/**
	 * Returns the current task status.
	 * */
	public TaskStatus getStatus(){
		return status;
	}
	
	/**
	 * Signals that this task should not START if it hasn't started yet.
	 * There is no guarantee that a Task will implement this functionality.
	 * */
	public void cancel(){
		cancelled = true;
	}
	
	/**
	 * Returns the task priority. Default is NORMAL.
	 * */
	public TaskPriority getTaskPriority(){
		return TaskPriority.NORMAL;
	}
	
	/**
	 * List of status listeners.
	 * */
	protected List<TaskStatusListener> statusListeners = new ArrayList<TaskStatusListener>();
	
	public void addTaskStatusListener(TaskStatusListener listener){
		statusListeners.add(listener);
	}
	
	/**
	 * Signals all listeners that the task status has changed.
	 * */
	protected void changeStatus(TaskStatus newValue){
		TaskStatus oldValue = status;
		status = newValue;
		for(TaskStatusListener tsl: statusListeners){
			tsl.statusChanged(oldValue, newValue);
		}
	}

	
	/**
	 * Compares two tasks according to their priority.
	 * */
	public int compareTo(Task tsk) {
		return getTaskPriority().ordinal()-tsk.getTaskPriority().ordinal();
	}

	/**
	 * Returns the time the task has started running.
	 * */
	public final Date getTaskStartTime() {
		return taskStartTime;
	}

	public boolean isToAddToReport() {
		return false;
	} 
	
	
	public String toString(){
		return getName();
	}
}
